package com.ljl.mvvmdemo.viewmodel

import android.os.Bundle
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ljl.mvvmdemo.net.BaseResponse
import com.ljl.mvvmdemo.util.BUNDLE
import com.ljl.mvvmdemo.util.CLASS
import com.ljl.mvvmdemo.util.REQUEST_CODE
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*

/**
 * ViewModel 基类
 * created by luojialun on 2024/3/20
 */
open class BaseViewModel : ViewModel(), LifecycleListener {

    var startActivityEvent: MutableLiveData<Map<String, Any>> = MutableLiveData()
    var showLoadingEvent: MutableLiveData<String> = MutableLiveData()
    var dismissLoadingEvent: MutableLiveData<Boolean> = MutableLiveData()

    override fun onCreate() {
    }

    override fun onStart() {
    }

    override fun onResume() {
    }

    override fun onPause() {
    }

    override fun onStop() {
    }

    override fun onDestroy() {
    }

    fun showLoading(tip: String = "") {
        showLoadingEvent.postValue(tip)
    }

    fun dismissLoading() {
        dismissLoadingEvent.postValue(true)
    }

    fun startActivity(clz: Any, bundle: Bundle? = null) {
        startActivityForResult(clz, bundle)
    }

    fun startActivityForResult(clz: Any, bundle: Bundle? = null, requestCode: Int = -1) {
        val params: MutableMap<String, Any> = HashMap()
        params[CLASS] = clz
        bundle?.let {
            params[BUNDLE] = it
        }
        params[REQUEST_CODE] = requestCode
        startActivityEvent.postValue(params)
    }

    /**
     * 发起请求
     * @param block 请求块
     * @param success 请求成功数据
     * @param failure 服务器错误
     * @param error 网络错误及其他
     */
    fun <T> requestOnUI(block: suspend () -> BaseResponse<T>, success: (data: T?) -> Unit,
                        failure: (code: String, msg: String) -> Unit, error: (e: Throwable) -> Unit,
                        showLoading: Boolean = false, dismissLoadingComplete: Boolean = true) {
        viewModelScope.launch(Dispatchers.IO) {
            kotlin.runCatching {
                withContext(Dispatchers.Main) {
                    if (showLoading) {
                        showLoading()
                    }
                }
                block()
            }.onSuccess {
                withContext(Dispatchers.Main) {
                    if (showLoading && dismissLoadingComplete) {
                        dismissLoading()
                    }
                    if ("0" == it.code) {
                        success(it.data)
                    } else {
                        failure(it.code, it.msg)
                    }
                }
            }.onFailure {
                if (showLoading && dismissLoadingComplete) {
                    dismissLoading()
                }
                withContext(Dispatchers.Main) {
                    error(it)
                }
            }
        }
    }

}
